#ifndef CONTAINERWRAPPER_H_
#define CONTAINERWRAPPER_H_

#include <stack>
#include <vector>
//#include "deleteCustomClasses.h"
//#include "stdafx.h"
#include <math.h>
#include "enums.h"

//Forward class/struct declarations
struct Action;
struct Event;
class Behaviour;


class StackI
{
private:
	std::stack<Behaviour*> stack_intern;
	int size;
public:
	StackI();

	void push(Behaviour *b);
	void pop();
	Behaviour* peek();
	bool isEmpty();
	bool updateBehaviour(float _deltaSeconds);
	int getNumberOfBehaviours(){ return size; }

	bool behaviourHigherPriorityThanStack(Behaviour* newBehaviour);

	~StackI();
};

class ActionList
{
private:
	std::vector <Action*> vector_intern;
	int size;

public:
	ActionList(){ size = 0; }

	void add(Action* a){ vector_intern.push_back(a); size++; }
	Action* getFront()
	{
		if (size > 0)
			return vector_intern[0];
		return NULL;
	}
	Action* getAt(int i)
	{
		if (size >= i)
			return vector_intern[i];
		return NULL;
	}
	bool isEmpty()
	{
		if (size > 0)
			return false;

		return true;
	}

	int getSize()
	{
		return size;
	}

	~ActionList();


};

class EventList
{
private:
	std::vector <Event*> vector_intern;
	int size;

public:
	EventList(){ size = 0; }

	void add(Event* a){ vector_intern.push_back(a); size++; }
	Event* getFront()
	{
		if (size > 0)
			return vector_intern[0];
		return NULL;
	}
	Event* getAt(int i)
	{
		if (size >= i)
			return vector_intern[i];
		return NULL;
	}
	bool isEmpty()
	{
		if (size > 0)
			return false;

		return true;
	}
	
	int getSize()
	{
		return size;
	}

	void setToNull(int i)
	{
		if (size >= i)
			vector_intern[i] = NULL;
	}

	void emptyList()
	{
		while (!vector_intern.empty())
		{
			vector_intern.pop_back();
		}
		size = 0;
	}

	~EventList();


};

class Vector3D
{
private:

public:
	float x, y, z;

	Vector3D(float _x, float _y, float _z) { x = _x; y = _y; z = _z; }

	float magnitude()
	{
		return sqrt((x*x) + (y*y) + (z*z));
	}
	void normalise()
	{
		float mag = magnitude();
		x /= mag;
		y /= mag;
		z /= mag;
	}
	void scale(float scalar)
	{
		x *= scalar;
		y *= scalar;
		z *= scalar;
	}

	void invertDirection()
	{
		x = 0 - x;
		y = 0 - y;
		z = 0 - z;
	}


};


class BehaviourList
{
private:
	std::vector <Behaviour*> vector_intern;
	int size;

public:
	BehaviourList(){ size = 0; }

	void add(Behaviour* a){ vector_intern.push_back(a); size++; }
	Behaviour* getFront()
	{
		if (size > 0)
			return vector_intern[0];
		return NULL;
	}
	Behaviour* getAt(int i)
	{
		if (size >= i)
			return vector_intern[i];
		return NULL;
	}
	void setAt(int i, Behaviour* _behaviour)
	{
		if (size >= i)
			vector_intern[i] = _behaviour;
	}

	bool isEmpty()
	{
		if (size > 0)
			return false;

		return true;
	}

	int getSize()
	{
		return size;
	}

	void removeAt(int i)
	{
		vector_intern.erase(vector_intern.begin() + i);
		size--;
	}

	void nullWithoutRemoving(int i)
	{
		vector_intern[i] = NULL;
	}


	~BehaviourList();


};

#endif